﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Web.Script.Services;
using System.Web.Services;
using Ext.Net;
using Newtonsoft.Json.Linq;

namespace KamLib
{

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [ScriptService]
    public class ExtUilService : WebService
    {

        public readonly UilContext UilContext = new UilContext();

        protected override void Dispose(bool disposing)
        {
            UilContext.Dispose();
            base.Dispose(disposing);
        }


        #region WebMethods

        [WebMethod]
        public DirectResponse Invoke(string key, string name, Dictionary<string, object> args)
        {
            try
            {
                var e = UilMethod.Invoke(
                    UilContext, ExtUilKeys.KeyFromJson(key), name,
                    AddRequestParams(args ?? new Dictionary<string, object>(), InvokeParamNames)
                );

                var response = new XControlResponse();
                if (e.Result != null)
                    response.Params.AddRaw("result", e.Result);
                UilContext.Notifications.Show();
                return response;
            }
            catch (Exception ex)
            {
                throw new HtmlException(ex);
            }
        }
        private static readonly string[] InvokeParamNames = new[] { "key", "name", "args" };


        [WebMethod]
        public object Handle(string key, string name, Dictionary<string, object> args)
        {
            try
            {
                var e = UilMethod.Invoke(
                    UilContext, ExtUilKeys.KeyFromJson(key), name,
                    AddRequestParams(args, InvokeParamNames)
                );
                return e.Result;
            }
            catch (Exception ex)
            {
                throw new HtmlException(ex);
            }
        }


        #endregion


        #region Tools

        /// <summary>
        /// Добавляет к аргументам все нестандартные параметры запроса
        /// </summary>
        /// <param name="args"></param>
        /// <param name="ignoreRequestParams">Не добавляет параметры с такими именами</param>
        /// <returns></returns>
        public IDictionary<string, object> AddRequestParams(IDictionary<string, object> args, string[] ignoreRequestParams = null)
        {
            if (args == null) return null;

            Context.Request.InputStream.Seek(0, SeekOrigin.Begin);
            var sr = new StreamReader(Context.Request.InputStream);
            var sprms = sr.ReadToEnd();
            if (sprms.isfull())
            {
                if (sprms.Contains("{"))
                {
                    var prms = JSON.Deserialize<Dictionary<string, object>>(sprms);
                    foreach (var prm in prms)
                    {
                        if (ignoreRequestParams == null || !ignoreRequestParams.Contains(prm.Key))
                            args[prm.Key] = prm.Value;
                    }
                }
                else
                {
                    foreach (var prm1 in sprms.Split('&'))
                    {
                        if (prm1.isnull()) continue;
                        var prm2 = prm1.Split('=');
                        if (prm2.Length < 2) continue;
                        var name = Server.UrlDecode(prm2[0]);
                        if (ignoreRequestParams == null || !ignoreRequestParams.Contains(name))
                            args[name] = Server.UrlDecode(prm2[1]);
                    }
                }
            }

            return args;
        }

        #endregion


    }

}
